package hr.sting.droidorm;

import android.database.Cursor;
import hr.sting.beans.PropertyInfo;
import hr.sting.droidorm.types.OrmTypeMapper;

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;

/**
 * @author mstipanov
 * @since 10.07.2010. 17:02:39
 */
public class DroidOrmCursor<T> implements Iterator<T> {
    private Cursor cursor;
    private OrmEntityDescriptor<T> descriptor;
    private OrmTypeMapper ormTypeMapper;

    public DroidOrmCursor(Cursor cursor, OrmEntityDescriptor<T> descriptor, OrmTypeMapper ormTypeMapper) {
        this.cursor = cursor;
        this.descriptor = descriptor;
        this.ormTypeMapper = ormTypeMapper;
    }

    @Override
    public boolean hasNext() {
        return !cursor.isLast() && !cursor.isAfterLast() ;
    }

    @Override
    public T next() {
        cursor.moveToNext();
        try {
            return createEntity();
        } catch (Exception e) {
            throw new OrmException(e);
        }
    }

    private T createEntity() throws IllegalAccessException, InstantiationException, InvocationTargetException {
        T t = descriptor.getEntityType().newInstance();

        for (String columnName : cursor.getColumnNames()) {
            PropertyInfo propertyInfo = descriptor.getProperty(columnName);
            if (null == propertyInfo) {
                throw new OrmException("No mapping for column: " + columnName + " for class " + descriptor.getEntityType());
            }

            int index = cursor.getColumnIndex(columnName);


            propertyInfo.setValue(t, ormTypeMapper.getCursorValue(cursor, index, propertyInfo.getPropertyType()));
        }

        return t;
    }

    @Override
    public void remove() {
    }
}
